from typing import List

import httpx
from databases import Database
from fastapi import APIRouter, Depends, Query

from app.api.routes.websocket_api import manager
from common.utils import format_open_number
from core.db.deps import get_db

router = APIRouter(prefix="/lottery", tags=["lottery"])


@router.route("/dataSimple", methods=["GET"])
async def get_lottery_data_simple(
    lottery_code: str = Query("Ethereum1-Cash5", alias="code", description="Lottery code"),
    limit: int = Query(1, description="Number of records to fetch"),
    date: str | None = Query(None, description="Date"),
    db: Database=Depends(get_db)
):
    limit = min(limit, 2000)
    meta_query = "SELECT table_name FROM lottery_meta WHERE lottery_code = :lottery_code"

    meta_data = await db.fetch_one(query=meta_query, values={"lottery_code": lottery_code})
    if not meta_data:
        return {"error": "Invalid lottery code"}
    if date:
        lottery_query = "SELECT gmt_bet_no, open_number FROM :table_name WHERE DATE(open_time)=:date ORDER BY open_time DESC LIMIT :limit"
        values = {"table_name": meta_data["table_name"], "limit": limit, "date": date}
    else:
        lottery_query = "SELECT gmt_bet_no, open_number FROM :table_name ORDER BY open_time DESC LIMIT :limit"
        values = {"table_name": meta_data["table_name"], "limit": limit}
    lottery_data = await db.fetch_all(query=lottery_query, values=values)
    if not lottery_data:
        return {"error": "No data found for the given parameters"}
    formatted_data = [
        f"{row['gmt_bet_no']},{format_open_number(row['open_number'])}"
        for row in lottery_data
    ]
    data = "^".join(formatted_data)
    return {"data": data}


@router.route("/dataSimple", methods=["GET"])
async def get_lottery_data(
    lottery_code: str = Query("Ethereum1-Cash5", alias="code", description="Lottery code"),
    limit: int = Query(1, description="Number of records to fetch"),
    date: str | None = Query(None, description="Date"),
    db: Database=Depends(get_db)
):
    limit = min(limit, 2000)
    meta_query = "SELECT table_name FROM lottery_meta WHERE lottery_code = :lottery_code"

    meta_data = await db.fetch_one(query=meta_query, values={"lottery_code": lottery_code})
    if not meta_data:
        return {"error": "Invalid lottery code"}
    if date:
        lottery_query = "SELECT gmt_bet_no, open_number FROM :table_name WHERE DATE(open_time)=:date ORDER BY open_time DESC LIMIT :limit"
        values = {"table_name": meta_data["table_name"], "limit": limit, "date": date}
    else:
        lottery_query = "SELECT gmt_bet_no, open_number FROM :table_name ORDER BY open_time DESC LIMIT :limit"
        values = {"table_name": meta_data["table_name"], "limit": limit}
    lottery_data = await db.fetch_all(query=lottery_query, values=values)
    if not lottery_data:
        return {"error": "No data found for the given parameters"}
    formatted_data = [
        f"{row['gmt_bet_no']},{format_open_number(row['open_number'])}"
        for row in lottery_data
    ]
    return {"data": formatted_data, "lotteryCode": lottery_code, "lotteryName": ""}


@router.route("/query", methods=["GET"])
async def query_lottery_data(
    lottery_code: str = Query("Ethereum1-Cash5", alias="code", description="Lottery code"),
    gmt_bet_no: int = Query(..., description="Bet number"),
    db: Database=Depends(get_db)
):
    meta_query = "SELECT table_name, lottery_name FROM lottery_meta WHERE lottery_code = :lottery_code"

    meta_data = await db.fetch_one(query=meta_query, values={"lottery_code": lottery_code})
    if not meta_data:
        return {"error": "Invalid lottery code"}

    lottery_query = "SELECT gmt_bet_no, open_number FROM :table_name WHERE CAST(gmt_bet_no AS UNSIGNED) > :gmt_bet_no ORDER BY CAST(gmt_bet_no AS UNSIGNED) ASC"
    values = {"table_name": meta_data["table_name"], "gmt_bet_no": gmt_bet_no}
    lottery_data = await db.fetch_all(query=lottery_query, values=values)
    return {}


@router.route("/querySimple", methods=["GET"])
async def query_lottery_data(
    lottery_code: str = Query("Ethereum1-Cash5", alias="code", description="Lottery code"),
    gmt_bet_no: int = Query(..., description="Bet number"),
    db: Database=Depends(get_db)
):
    meta_query = "SELECT table_name, lottery_name FROM lottery_meta WHERE lottery_code = :lottery_code"

    meta_data = await db.fetch_one(query=meta_query, values={"lottery_code": lottery_code})
    if not meta_data:
        return {"error": "Invalid lottery code"}

    lottery_query = "SELECT gmt_bet_no, open_number FROM :table_name WHERE CAST(gmt_bet_no AS UNSIGNED) > :gmt_bet_no ORDER BY CAST(gmt_bet_no AS UNSIGNED) ASC"
    values = {"table_name": meta_data["table_name"], "gmt_bet_no": gmt_bet_no}
    lottery_data = await db.fetch_all(query=lottery_query, values=values)
    return {}


@router.post("/push-biz-open-collection")
async def push_biz_open_collection(
    payload: dict,
    user_list: List[str]
):
    """
    向外部接口发起请求，并通过 websocket 向指定用户推送结果。
    """
    async with httpx.AsyncClient() as client:
        try:
            response = await client.post(
                "http://外部接口地址/lotterys/biz-open-collection/push",
                json=payload,
                timeout=10.0
            )
            result = response.json()
        except Exception as e:
            await manager.send_to_users(user_list, f"推送失败: {str(e)}")
            return {"error": "外部接口请求失败", "detail": str(e)}
    # 定向推送结果
    await manager.send_to_users(user_list, f"推送结果: {result}")
    return {"result": result}
